package parser;

import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class Lexemiser {
	
	Map<String, Lexem> wyrazeniaMap = new TreeMap<String, Lexem>();
	Set<Character> rozdzielajaceSet = new TreeSet<Character>();
	
	public Lexemiser() {
		wyrazeniaMap.put("(", new NawiasOkrOtwierajacy());
		wyrazeniaMap.put(")", new NawiasOkrZamykajacy());
		wyrazeniaMap.put("[", new NawiasKwaOtwierajacy());
		wyrazeniaMap.put("]", new NawiasKwaZamykajacy());
		wyrazeniaMap.put("]", new NawiasKwaZamykajacy());
		wyrazeniaMap.put("~", new Negacja());
		wyrazeniaMap.put("|", new Alternatywa());
		wyrazeniaMap.put("&", new Koniunkcja());
		wyrazeniaMap.put("=", new Rownosc());
		wyrazeniaMap.put("<", new Inkluzja());
		wyrazeniaMap.put("T", new True());
		wyrazeniaMap.put("F", new False());
		wyrazeniaMap.put("all", new KwantyfikatorOgolny());
		wyrazeniaMap.put("some", new KwantyfikatorSzczegolny());
		
		rozdzielajaceSet.add('(');
		rozdzielajaceSet.add(')');
		rozdzielajaceSet.add('[');
		rozdzielajaceSet.add(']');
		rozdzielajaceSet.add('~');
		rozdzielajaceSet.add('|');
		rozdzielajaceSet.add('&');
		rozdzielajaceSet.add('<');
		rozdzielajaceSet.add('=');
	}
	
	public Lexem dajCName(String s) { 
		if(s.charAt(0) >= 'A' && s.charAt(0) <= 'Z')
			return new CName(s);

		return null;
	}
	
	public Lexem dajRName(String s) { 
		if(s.charAt(0) >= 'a' && s.charAt(0) <= 'z')
			return new RName(s);

		return null;
	}

	public Lexem klasyfikuj(String s) throws WyjatekPrzyParsowaniu {
		Lexem lex = wyrazeniaMap.get(s);
		if(lex != null)
			return lex;
		lex = dajCName(s);
		if(lex != null)
			return lex;
		lex = dajRName(s);
		if(lex != null)
			return lex;
		else throw (new NieznaneWyrazenie(s));
	}
	
	public boolean czyRozdzielajacy(char c) {
		return rozdzielajaceSet.contains(c);
	}
	
	public ArrayList<Lexem> podzielNaLexemy(String s) throws WyjatekPrzyParsowaniu {
		
		ArrayList<String> sl = new ArrayList<String>();
		ArrayList<Lexem> ll = new ArrayList<Lexem>();

		String t = "";
		
		for(int i = 0; i < s.length(); i++) {
			if(czyRozdzielajacy(s.charAt(i))) {
				t += " " + s.charAt(i) + " ";
			}
			else 
				t += s.charAt(i);
		}

		s = t;
		
		t = new String("");
		boolean trzebaZapisac = false;
		for(int i = 0; i < s.length(); i++) {
			if(s.charAt(i) != ' ') {
				trzebaZapisac = true;
				t += s.charAt(i);
			}
			else if(trzebaZapisac) {
				sl.add(t);
				t = new String("");
				trzebaZapisac = false;
			}
		}
		if(trzebaZapisac)
			sl.add(t);
		
		for(int i = 0; i < sl.size(); i++) {
			ll.add(klasyfikuj(sl.get(i)));
		}

		return ll;
	}
	
}